package com.itranswarp.weibo.api;

import java.util.HashMap;
import java.util.Map;

/**
 * Json object.
 * 
 * @author Michael Liao (askxuefeng@gmail.com)
 */
public class JsonObject {

	Map<String, Object> map = new HashMap<String, Object>();

	@SuppressWarnings("unchecked")
	public <T> T get(String field) {
		if ( ! has(field))
			throw new JsonException("No such field '" + field + "'");
		return (T) map.get(field);
	}

	@SuppressWarnings("unchecked")
	public <T> T get(String field, T defaultValue) {
		if ( ! has(field))
			return defaultValue;
		return (T) map.get(field);
	}

	public <T> void set(String field, T value) {
		map.put(field, value);
	}

	public boolean has(String field) {
		return map.containsKey(field);
	}

	public String toString() {
		StringBuilder sb = new StringBuilder(128);
		appendObject(sb, 0, this);
		return sb.toString();
	}

	void appendLevel(StringBuilder sb, int level) {
		for (int i=0; i<level; i++) {
			sb.append("    ");
		}
	}

	void appendObject(StringBuilder sb, int level, JsonObject jo) {
		appendLevel(sb, level);
		sb.append("{\n");
		for (String key : jo.map.keySet()) {
			appendLevel(sb, level + 1);
			sb.append("\"").append(key).append("\" : ");
			appendValue(sb, level + 1, jo.map.get(key));
			sb.append(",\n");
		}
		sb.deleteCharAt(sb.length() - 1);
		appendLevel(sb, level);
		sb.append("}\n");
	}

	void appendValue(StringBuilder sb, int level, Object value) {
		if (value==null) {
			appendLevel(sb, level);
			sb.append("null");
		}
		else if (value.getClass().isArray()) {
			appendLevel(sb, level);
			sb.append("[");
			Object[] arr = (Object[]) value;
			for (Object o : arr) {
				appendValue(sb, level + 1, o);
				sb.append(", ");
			}
			sb.append("]");
		}
		else if (value instanceof JsonObject) {
			appendObject(sb, level + 1, (JsonObject) value);
		}
		else {
			sb.append(value);
		}
	}
}
